// drawingarea.cpp
#include "drawingarea.h"
#include <QGraphicsPixmapItem>
#include <QFile>
#include <QDataStream>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPixmap>
#include <QDebug>
#include <QGraphicsItem>
#include <QWheelEvent>
#include <QMimeData>
#include <QDrag>

// 在DrawingArea构造函数中初始化指针
DrawingArea::DrawingArea(QWidget *parent) : QGraphicsView(parent),
    currentComponent(nullptr), currentWire(nullptr), isDrawingWire(false)
{
    qDebug() << "DrawingArea constructing";
    scene = new QGraphicsScene(this);
    setScene(scene);
    setupScene();
    setRenderHint(QPainter::Antialiasing);
    setDragMode(QGraphicsView::RubberBandDrag);

    // 确保scene已创建
    if(!scene) {
        qCritical() << "Failed to create QGraphicsScene";
        return;
    }
    qDebug() << "DrawingArea constructed with scene:" << scene;
}

void DrawingArea::setupScene()
{
    scene->setSceneRect(0, 0, 2000, 2000);
    scene->setBackgroundBrush(QBrush(Qt::white));
}

void DrawingArea::setCurrentComponent(Component* component)
{
    m_currentComponentToPlace = component;
}

void DrawingArea::addComponent(Component *component)
{
    if (!component) return;

    Component *newComp = new Component(*component);
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(newComp->icon().pixmap(64, 64));
    item->setPos(mapToScene(viewport()->rect().center()));
    item->setData(0, QVariant::fromValue(newComp)); // 使用 QVariant::fromValue
    item->setFlag(QGraphicsItem::ItemIsMovable, true);
    item->setFlag(QGraphicsItem::ItemIsSelectable, true);
    scene->addItem(item);
    components.append(newComp);
}

void DrawingArea::clear()
{
    scene->clear();
    components.clear();
    wires.clear();
    currentComponent = nullptr;
    currentWire = nullptr;
    isDrawingWire = false;
}

bool DrawingArea::saveToFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly))
        return false;

    QDataStream out(&file);
    // 保存场景中的项目
    // 实际实现需要更复杂的序列化
    return true;
}

bool DrawingArea::loadFromFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly))
        return false;

    clear();
    QDataStream in(&file);
    // 加载场景中的项目
    // 实际实现需要更复杂的反序列化
    return true;
}

bool DrawingArea::exportToImage(const QString &fileName)
{
    QPixmap pixmap(scene->sceneRect().size().toSize());
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    scene->render(&painter);
    return pixmap.save(fileName);
}

void DrawingArea::mousePressEvent(QMouseEvent *event)
{
    // 只处理组件移动，不处理组件创建
    if (event->button() == Qt::LeftButton) {
        QGraphicsItem* item = itemAt(event->pos());
        if (item) {
            m_currentDraggingItem = item;
            setCursor(Qt::ClosedHandCursor);
        }
    }
    else if (event->button() == Qt::MiddleButton) {
        m_lastPanPoint = event->pos();
        setCursor(Qt::OpenHandCursor);
    }

    QGraphicsView::mousePressEvent(event);
}

void DrawingArea::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::MiddleButton) {
        // 获取当前和上一次的鼠标位置（场景坐标）
        QPointF currentScenePos = mapToScene(event->pos());
        QPointF lastScenePos = mapToScene(m_lastPanPoint);

        // 计算移动增量
        QPointF delta = currentScenePos - lastScenePos;

        // 计算新的视图中心
        QPointF currentCenter = mapToScene(viewport()->rect().center());
        QPointF newCenter = currentCenter - delta;

        // 移动视图
        centerOn(newCenter);
        m_lastPanPoint = event->pos();
    }
    else if ((event->buttons() & Qt::LeftButton) && m_currentDraggingItem) {
        // 移动选中的项目
        QPointF scenePos = mapToScene(event->pos());
        m_currentDraggingItem->setPos(scenePos);
    }

    QGraphicsView::mouseMoveEvent(event);
}

void DrawingArea::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && m_currentDraggingItem) {
        // 结束拖拽
        m_currentDraggingItem = nullptr;
        setCursor(Qt::ArrowCursor);
    }
    else if (event->button() == Qt::MiddleButton) {
        setCursor(Qt::ArrowCursor);
    }

    QGraphicsView::mouseReleaseEvent(event);
}

void DrawingArea::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && m_currentComponentToPlace) {
        QPointF scenePos = mapToScene(event->pos()); // 获取鼠标双击位置
        addComponentAtPosition(m_currentComponentToPlace, scenePos); // 在指定位置添加组件
        m_currentComponentToPlace = nullptr; // 重置当前组件
        emit componentPlaced(); // 发射组件放置信号
    }
    QGraphicsView::mouseDoubleClickEvent(event);
    qDebug() << "Double click at position:" << mapToScene(event->pos());
}

void DrawingArea::wheelEvent(QWheelEvent *event)
{
    // 滚轮缩放视图
    const double scaleFactor = 1.15;
    if (event->angleDelta().y() > 0) {
        scale(scaleFactor, scaleFactor);
    } else {
        scale(1.0 / scaleFactor, 1.0 / scaleFactor);
    }
}

void DrawingArea::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasText()) {
        event->acceptProposedAction();
        qDebug() << "Drag entered with mime data:" << event->mimeData()->text();
    } else {
        event->ignore();
    }
}

void DrawingArea::dropEvent(QDropEvent *event)
{
    if (!event->mimeData()->hasText()) {
        event->ignore();
        return;
    }

    QString compName = event->mimeData()->text();
    QPointF dropPos = mapToScene(event->pos());
    qDebug() << "Drop at position:" << dropPos;

    emit componentRequested(compName, dropPos);
    event->acceptProposedAction();
}

void DrawingArea::addComponentAtPosition(Component *component, const QPointF &pos)
{
    if (!component) return;

    Component *newComp = new Component(*component);
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(newComp->icon().pixmap(64, 64));
    item->setPos(pos);
    item->setData(0, QVariant::fromValue(newComp)); // 使用 QVariant::fromValue
    item->setFlag(QGraphicsItem::ItemIsMovable, true);
    item->setFlag(QGraphicsItem::ItemIsSelectable, true);
    scene->addItem(item);
    components.append(newComp);
}

void DrawingArea::startDrawingWire(Component *component, const QPointF &pos)
{
    currentWire = new Wire();
    currentWire->setStartComponent(component);
    currentWire->setStartPos(pos);
    scene->addItem(currentWire);
    isDrawingWire = true;
}

void DrawingArea::continueDrawingWire(const QPointF &pos)
{
    if (currentWire) {
        currentWire->addPoint(pos);
    }
}

void DrawingArea::finishDrawingWire(Component *component, const QPointF &pos)
{
    if (currentWire) {
        currentWire->setEndComponent(component);
        currentWire->setEndPos(pos);
        wires.append(currentWire);
        currentWire = nullptr;
        isDrawingWire = false;
    }
}

DrawingArea::~DrawingArea()
{
    delete scene;
}
